package com.ai.learning.inference.controller;

import com.ai.learning.framework.common.util.IdGenerator;
import com.ai.learning.framework.common.util.RedisHelper;
import com.ai.learning.framework.core.exception.BusinessException;
import com.ai.learning.framework.core.exception.ErrorCode;
import com.ai.learning.framework.core.model.Result;
import com.ai.learning.inference.dto.InferenceRequest;
import com.ai.learning.inference.dto.InferenceResponse;
import com.ai.learning.inference.service.AiInferenceService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.validation.Valid;
import javax.validation.constraints.NotBlank;

/**
 * AI推理控制器
 * 提供高性能AI推理服务，与Django后端协同工作
 */
@Slf4j
@RestController
@RequestMapping("/api/v1/ai/inference")
@RequiredArgsConstructor
@Validated
public class AiInferenceController {

    private final AiInferenceService aiInferenceService;
    private final RedisHelper redisHelper;
    private final IdGenerator idGenerator;

    /**
     * 执行AI推理
     * 与Django智能体模型集成，提供高性能推理能力
     */
    @PostMapping("/predict")
    public Result<InferenceResponse> predict(@Valid @RequestBody InferenceRequest request) {
        log.info("收到AI推理请求: agentId={}, inputText={}", 
                request.getAgentId(), request.getInputText());

        // 1. 参数校验
        if (request.getInputText().length() > 10000) {
            throw BusinessException.of(ErrorCode.VALIDATION_FAILED, "输入文本过长，最大支持10000字符");
        }

        try {
            // 2. 生成推理任务ID
            String taskId = idGenerator.businessId("INFERENCE_");
            
            // 3. 缓存推理任务状态
            redisHelper.set("inference:task:" + taskId, "PROCESSING", 300); // 5分钟过期
            
            // 4. 执行AI推理
            InferenceResponse response = aiInferenceService.performInference(request);
            response.setTaskId(taskId);
            
            // 5. 缓存推理结果
            redisHelper.set("inference:result:" + taskId, response, 3600); // 1小时过期
            
            // 6. 更新任务状态
            redisHelper.set("inference:task:" + taskId, "COMPLETED", 3600);
            
            log.info("AI推理完成: taskId={}, responseLength={}", 
                    taskId, response.getOutputText().length());
            
            return Result.success(response);
            
        } catch (Exception e) {
            log.error("AI推理失败: agentId={}", request.getAgentId(), e);
            throw BusinessException.of(ErrorCode.BUSINESS_ERROR, "AI推理服务暂时不可用");
        }
    }

    /**
     * 查询推理任务状态
     */
    @GetMapping("/task/{taskId}/status")
    public Result<String> getTaskStatus(@PathVariable @NotBlank String taskId) {
        Object status = redisHelper.get("inference:task:" + taskId);
        
        if (status == null) {
            throw BusinessException.of(ErrorCode.DATA_NOT_FOUND, "推理任务不存在或已过期");
        }
        
        return Result.success(status.toString());
    }

    /**
     * 获取推理结果
     */
    @GetMapping("/task/{taskId}/result")
    public Result<InferenceResponse> getTaskResult(@PathVariable @NotBlank String taskId) {
        Object result = redisHelper.get("inference:result:" + taskId);
        
        if (result == null) {
            throw BusinessException.of(ErrorCode.DATA_NOT_FOUND, "推理结果不存在或已过期");
        }
        
        return Result.success((InferenceResponse) result);
    }

    /**
     * 批量推理接口
     * 支持同时处理多个推理请求
     */
    @PostMapping("/batch-predict")
    public Result<String> batchPredict(@Valid @RequestBody InferenceRequest[] requests) {
        log.info("收到批量推理请求，数量: {}", requests.length);

        // 生成批量任务ID
        String batchTaskId = idGenerator.businessId("BATCH_INFERENCE_");
        
        // 异步处理批量推理
        aiInferenceService.performBatchInference(batchTaskId, requests);
        
        return Result.success("批量推理任务已提交，任务ID: " + batchTaskId, batchTaskId);
    }

    /**
     * 健康检查接口
     * 供Django后端或网关进行服务可用性检查
     */
    @GetMapping("/health")
    public Result<String> health() {
        try {
            // 检查Redis连接
            redisHelper.set("health_check", "ok", 5);
            
            // 检查AI推理服务
            boolean aiServiceHealthy = aiInferenceService.healthCheck();
            
            if (aiServiceHealthy) {
                return Result.success("AI推理服务正常");
            } else {
                return Result.error(ErrorCode.SERVICE_UNAVAILABLE.getCode(), "AI推理服务异常");
            }
            
        } catch (Exception e) {
            log.error("健康检查失败", e);
            return Result.error(ErrorCode.SERVICE_UNAVAILABLE.getCode(), "服务健康检查失败");
        }
    }
}